package com.winit.openapi.wh.allocation.controller;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.winit.common.query.Page;
import com.winit.common.query.Searchable;
import com.winit.common.query.Sort;
import com.winit.common.query.Sort.Direction;
import com.winit.common.spi.context.CommandContext;
import com.winit.oms.spi.allocation.command.order.AllocationOrderCommand;
import com.winit.oms.spi.allocation.command.order.CancelCrossDumpOrderCommand;
import com.winit.oms.spi.allocation.command.order.CreateCrossDumpOrderCommand;
import com.winit.oms.spi.allocation.command.order.QueryAllocationOrderCommand;
import com.winit.oms.spi.allocation.command.order.QueryOrderBySellerCommand;
import com.winit.oms.spi.allocation.command.order.ReOrderCommand;
import com.winit.oms.spi.allocation.command.order.SubmitAllocationOrderCommand;
import com.winit.oms.spi.allocation.command.order.VoidAllocationOrderCommand;
import com.winit.oms.spi.allocation.service.order.AllocationOrderService;
import com.winit.oms.spi.allocation.vo.AllocationOrderEnumContants;
import com.winit.oms.spi.allocation.vo.order.AllocationOrderVo;
import com.winit.oms.spi.inbound.InboundOrderService;
import com.winit.oms.spi.inbound.command.SearchInboundOrderCommand;
import com.winit.oms.spi.inbound.vo.InboundOrderVo;
import com.winit.oms.spi.order.command.OrderAndMerchandiseQueryCommand;
import com.winit.oms.spi.order.vo.OrderAndMerchandiseVo;
import com.winit.oms.spi.vo.v2.order.ProductInfo;
import com.winit.oms.spi.vo.v2.order.WarehouseInfo;
import com.winit.oms.spi.vo.v2.response.VoidResponse;
import com.winit.openapi.constants.ErrorCode;
import com.winit.openapi.controller.BaseController;
import com.winit.openapi.exception.ApiException;
import com.winit.openapi.model.RequestMsg;
import com.winit.openapi.model.ResponseMsg;
import com.winit.openapi.util.ValidateUtil;
import com.winit.openapi.wh.allocation.builder.AllocationOrderBuilder;
import com.winit.openapi.wh.allocation.vaildator.AllocationOrderfieldValidator;
import com.winit.ups.spi.constants.UpsConstants.StorageTransferType;
import com.winit.ups.spi.warehouse.StorageWarehouseService;
import com.winit.ups.spi.warehouse.WarehouseService;
import com.winit.ups.spi.warehouse.command.QueryDefaultPscConfigCommand;
import com.winit.ups.spi.warehouse.command.QueryStorageByDispatchCommand;
import com.winit.ups.spi.warehouse.vo.DefaultPscConfigVo;
import com.winit.ups.spi.warehouse.vo.DispatchStorageRelVo;

/**
 * 库间调拨单
 * 
 * @version <pre>
 * Author   Version     Date        Changes
 * cheng.li_guest   1.0         2016-12-11  Created
 * 
 * </pre>
 * @since 1.
 */
@Controller
@RequestMapping(value = "/wh/allocation")
public class AllocationOrderController extends BaseController {

    @Resource
    private AllocationOrderService  allocationOrderService;
    @Resource
    private WarehouseService        upsWarehouseService;
    @Resource
    private InboundOrderService     inboundOrderService;
    @Resource
    private StorageWarehouseService upsStorageWarehouseService;

    /**
     * 调拨单列表查询.
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/getOrderList")
    public String getOrderList(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        QueryOrderBySellerCommand command = new QueryOrderBySellerCommand();
        Object obj = requestMsg.getData();
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            AllocationOrderfieldValidator.validQueryByMainOrderParam(json);
            command = AllocationOrderBuilder.buildAllocationCommand(json);
            Searchable searchable = buildSearchablePageParams(json);
            if (AllocationOrderEnumContants.OrderStatus.DR.getStatus().equals(json.getString("orderStatus"))) {
                searchable.addSort(new Sort(Direction.DESC, "CREATED"));
            } else {
                searchable.addSort(new Sort(Direction.DESC, "CREATED"));
            }
            command.setSearchable(searchable);
        } else if (obj == null || StringUtils.isBlank(obj.toString())) {
            Searchable searchable = buildSearchablePageParams(null);
            command.setSearchable(searchable);
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        Page<AllocationOrderVo> pagelist = allocationOrderService.getOrderListBySeller(command);

        if (pagelist != null) {
            List<Map<String, Object>> datalist = buildOrderList(pagelist.getContent());
            Map<String, Object> pageMap = getPageParams(pagelist);
            Map<String, Object> data = new HashMap<String, Object>();
            data.put("list", datalist);
            data.put("pageParams", pageMap.get("pageParams"));
            responseMsg.setData(data);
        }
        return SUCCESS;
    }

    private List<Map<String, Object>> buildOrderList(List<AllocationOrderVo> datalist) {
        List<Map<String, Object>> rslist = new ArrayList<Map<String, Object>>();
        for (AllocationOrderVo order : datalist) {
            rslist.add(AllocationOrderBuilder.buildAllocationOrderListPageVo(order));
        }
        return rslist;
    }

    /**
     * 订单详情.
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/queryOrderByOrderNo")
    public String queryOrderByOrderNo(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        Object obj = requestMsg.getData();
        AllocationOrderCommand command = new AllocationOrderCommand();
        if (obj instanceof JSONObject) {
            JSONObject jsonObj = (JSONObject) obj;
            ValidateUtil.validNotNull(jsonObj, "orderNo");
            ValidateUtil.validMaxLength(jsonObj, "orderNo", 128);
            AllocationOrderVo vo = new AllocationOrderVo();
            vo.setOrderNo(jsonObj.getString("orderNo"));
            command.setOrderVo(vo);
            command.setCtx(CommandContext.getContext());
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        AllocationOrderVo allocationOrderVo = allocationOrderService.queryOrderByOrderNo(command); 
        Map<String, Object> map = new HashMap<String, Object>();
        if (null != allocationOrderVo) {
            map = AllocationOrderBuilder.buildReturnAllocationOrderInfo(allocationOrderVo);
        }
        responseMsg.setData(map);
        return SUCCESS;
    }

    /**
     * 第一步保存或更新
     * 
     * @param command
     * @param 返回订单号
     * @return
     */
    @RequestMapping(value = "/saveFirstStep")
    public String saveFirstStep(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        Object obj = requestMsg.getData();
        AllocationOrderCommand command = new AllocationOrderCommand();
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            AllocationOrderfieldValidator.validFirstStepField(json);
            AllocationOrderVo vo = AllocationOrderBuilder.buildFirstStep(json);
            command.setOrderNo(json.getString("orderNo"));
            command.setOrderVo(vo);
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        // 调用接口创建调拨单
        String orderNo = allocationOrderService.saveFirstStep(command);
        Map<String, Object> resultMap = new HashMap<String, Object>();
        resultMap.put("orderNo", orderNo);
        responseMsg.setData(resultMap);
        responseMsg.setMsg("SUCCESS");
        return SUCCESS;
    }

    /**
     * 第二步保存或更新
     * 
     * @param command
     * @return
     */
    @RequestMapping(value = "/saveSecondStep")
    public String saveSecondStep(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        Object obj = requestMsg.getData();
        AllocationOrderCommand command = new AllocationOrderCommand();
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            AllocationOrderfieldValidator.validSecondStepField(json);
            AllocationOrderVo vo = AllocationOrderBuilder.buildSecondStep(json);
            command.setOrderVo(vo);
            command.setOrderNo(json.getString("orderNo"));
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        // 调用接口创建调拨单
        long merchandiseId = allocationOrderService.saveSecondStep(command);
        Map<String, Object> resultMap = new HashMap<String, Object>();
        resultMap.put("merchandiseId", merchandiseId);
        responseMsg.setData(resultMap);
        responseMsg.setMsg("SUCCESS");
        return SUCCESS;
    }


    /**
     * 第三步保存或更新
     * 
     * @param command
     * @return
     */
    @RequestMapping(value = "/saveThirdStep")
    public String saveThirdStep(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        Object obj = requestMsg.getData();
        AllocationOrderCommand command = new AllocationOrderCommand();
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            AllocationOrderfieldValidator.validThirdStepField(json);
            AllocationOrderVo vo = AllocationOrderBuilder.buildThirdStep(json);
            command.setOrderVo(vo);
            command.setOrderNo(json.getString("orderNo"));
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        // TODO 要有返回信息费用详情
        String orderNo = allocationOrderService.saveThirdStep(command);
        Map<String, Object> resultMap = new HashMap<String, Object>();
        resultMap.put("orderNo", orderNo);
        responseMsg.setData(resultMap);
        responseMsg.setMsg("SUCCESS");
        return SUCCESS;
    }
    /**
     * 批量导出接口 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/exportOrderList")
    public String exportOrderList(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
    	 QueryOrderBySellerCommand command = new QueryOrderBySellerCommand();
         Object obj = requestMsg.getData();
         if (obj instanceof JSONObject) {
             JSONObject json = (JSONObject) obj;
             AllocationOrderfieldValidator.validQueryByMainOrderParam(json);
             command = AllocationOrderBuilder.buildAllocationCommand(json);
             Searchable searchable = buildSearchablePageParams(json);
             if (AllocationOrderEnumContants.OrderStatus.DR.getStatus().equals(json.getString("orderStatus"))) {
                 searchable.addSort(new Sort(Direction.DESC, "CREATED"));
             } else {
                 searchable.addSort(new Sort(Direction.DESC, "CREATED"));
             }
             command.setSearchable(searchable);
         } else if (obj == null || StringUtils.isBlank(obj.toString())) {
             Searchable searchable = buildSearchablePageParams(null);
             command.setSearchable(searchable);
         } else {
             throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
         }
         Page<AllocationOrderVo> pagelist = allocationOrderService.exportOrderList(command);
         
        if (pagelist != null) {
            List<Map<String, Object>> datalist = buildOrderList(pagelist.getContent());
            Map<String, Object> data = new HashMap<String, Object>();
            data.put("list", datalist);
            responseMsg.setData(data);
        }
        return SUCCESS;
    }

    /**
     * 提交订单(支持批量).
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/batchSubmit")
    public String batchSubmit(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        Object obj = requestMsg.getData();
        SubmitAllocationOrderCommand command = new SubmitAllocationOrderCommand();
        List<String> orderNoList = new ArrayList<String>();
        if (obj instanceof JSONObject) {
            JSONObject jsonObj = (JSONObject) obj;
            ValidateUtil.validNotNull(jsonObj, "orderNoList");
            JSONArray jsonArray = jsonObj.getJSONArray("orderNoList");
            if (null == jsonArray || jsonArray.size() == 0) {
                throw new ApiException(ErrorCode.FIELD_NOT_NULL, "orderNoList");
            }
            for (Object item : jsonArray) {
                JSONObject json = (JSONObject) item;
                ValidateUtil.validNotNull(json, "orderNo");
                ValidateUtil.validMaxLength(json, "orderNo", 64);
                orderNoList.add(json.getString("orderNo"));
            }
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        command.setOrderNoList(orderNoList);
        allocationOrderService.batchSubmit(command);
        return SUCCESS;
    }

    @RequestMapping(value = "/reOrder")
    public String reOrder(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        Object obj = requestMsg.getData();
        ReOrderCommand command = new ReOrderCommand();
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            ValidateUtil.validNotNull(json, "orderNo");
            ValidateUtil.validMaxLength(json, "orderNo", 64);
            command.setOrderNo(json.getString("orderNo"));
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        String orderNo = allocationOrderService.reOrder(command);
        Map<String, Object> resultMap = new HashMap<String, Object>();
        resultMap.put("orderNo", orderNo);
        responseMsg.setData(resultMap);
        responseMsg.setMsg("SUCCESS");
        return SUCCESS;
    }

    @RequestMapping(value = "/voidOrder")
    public String voidOrder(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        Object obj = requestMsg.getData();
        Map<String, Object> data = new HashMap<String, Object>();
        VoidAllocationOrderCommand command = new VoidAllocationOrderCommand();
        List<String> orderNoList = new ArrayList<String>();
        if (obj instanceof JSONObject) {
            JSONObject jsonObj = (JSONObject) obj;
            ValidateUtil.validNotNull(jsonObj, "orderNoList");
            JSONArray jsonArray = jsonObj.getJSONArray("orderNoList");
            if (null == jsonArray || jsonArray.size() == 0) {
                throw new ApiException(ErrorCode.FIELD_NOT_NULL, "orderNoList");
            }
            for (Object item : jsonArray) {
                JSONObject json = (JSONObject) item;
                ValidateUtil.validNotNull(json, "orderNo");
                ValidateUtil.validMaxLength(json, "orderNo", 64);
                orderNoList.add(json.getString("orderNo"));
            }
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        command.setOrderNos(orderNoList);
        VoidResponse result = allocationOrderService.voidOrder(command);
        if (result != null) {
            data.put("successNum", result.getSuccessNum());
            data.put("failNum", result.getFailNum());
            data.put("response", result.getErrorResultList());
            responseMsg.setData(data);
        }
        return SUCCESS;
    }

    /**
     * 根据出库单号查询调拨单列表
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/queryOrderByOutboundOrderNo")
    public String queryOrderByOutboundOrderNo(@ModelAttribute RequestMsg requestMsg,
                                              @ModelAttribute ResponseMsg responseMsg) {
        Object obj = requestMsg.getData();
        AllocationOrderCommand command = new AllocationOrderCommand();
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            ValidateUtil.validNotNull(json, "outboundOrderNo");
            ValidateUtil.validMaxLength(json, "outboundOrderNo", 128);
            command.setOrderNo(json.getString("outboundOrderNo"));
            Searchable searchable = buildSearchablePageParams(json);
            command.setSearchable(searchable);
            command.setCtx(CommandContext.getContext());
        }else if (obj == null || StringUtils.isBlank(obj.toString())) {
            Searchable searchable = buildSearchablePageParams(null);
            command.setSearchable(searchable);
        }  else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        Page<AllocationOrderVo> page = allocationOrderService.queryOrderByOutboundOrderNo(command);
        if (null != page && page.getContent()!=null&&page.getContent().size()>0) {
            Map<String, Object> map = new HashMap<String, Object>();
            List<Map<String, Object>> mapList = new ArrayList<Map<String, Object>>();
            for (AllocationOrderVo orderVo : page.getContent()) {
                Map<String, Object> orderVoMap = new HashMap<String, Object>();
                orderVoMap.put("orderNo", orderVo.getOrderNo());
                if (orderVo.getDispatchWarehouseInfo() != null) {
                    orderVoMap.put("warehouseName", orderVo.getDispatchWarehouseInfo().getWarehouseName());
                }
                orderVoMap.put("status", orderVo.getStatus());
                mapList.add(orderVoMap);
            }
            map.put("supplementOrderList", mapList);
            responseMsg.setData(map);
        }
        return SUCCESS;
    }
    
    /**
     * 查询补货订单详情.
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/queryReplenishmentOrder")
    public String queryReplenishmentOrder(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        Object obj = requestMsg.getData();
        QueryAllocationOrderCommand command = new QueryAllocationOrderCommand();
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            ValidateUtil.validNotNull(json, "warehouseCode");
            ValidateUtil.validMaxLength(json, "warehouseCode", 128);
            ValidateUtil.validNotNull(json, "merchandiseSerno");
            ValidateUtil.validMaxLength(json, "merchandiseSerno", 128);
            if (json.containsKey("merchandiseSerno")) {
                command.setMerchandiseSerno(json.getString("merchandiseSerno"));
            }
            if (json.containsKey("warehouseCode")) {
                command.setWarehouseCode(json.getString("warehouseCode"));
            }
            command.setCtx(CommandContext.getContext());
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        AllocationOrderVo orderVo = allocationOrderService.queryReplenishmentOrder(command);
        if (orderVo!=null) {
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("orderNo", orderVo.getOrderNo());
            map.put("qty", orderVo.getEstimateItemQty());
            responseMsg.setData(map);
        }
        return SUCCESS;
    }
    
    /**
     * 越库-第一步，生成一个转存单，并保存发货仓、存储仓、产品、客户等基本信息
     * 
     * @param command
     * @param 返回订单号
     * @return
     */
    @RequestMapping(value = "/crossDockFirstStep")
    public String crossDockFirstStep(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        Object obj = requestMsg.getData();
        CreateCrossDumpOrderCommand command = new CreateCrossDumpOrderCommand();
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            AllocationOrderfieldValidator.validCrossDockFirstStepField(json);
            AllocationOrderVo vo = AllocationOrderBuilder.buildCrossDockFirstStep(json);
           
            // 获取默认的psc实例编码
            DefaultPscConfigVo pscInstance = null;
            if (StringUtils.isNotBlank(vo.getMarkUp())) {  
                pscInstance = this.getDefaultPscInstanceCode(StorageTransferType.DELIVER_STORAGE.getVal());
                if (null == pscInstance) {
                    throw new ApiException(ErrorCode._02010250303);
                }
            } else {
                pscInstance = this.getDefaultPscInstanceCode(StorageTransferType.Cross_TO_STORAGE.getVal());
                if (null == pscInstance) {
                    throw new ApiException(ErrorCode._02010250303);
                }
            }
           
           
            
            // 获取入库单信息
            SearchInboundOrderCommand inboundOrderCommand = new SearchInboundOrderCommand();
            inboundOrderCommand.setCtx(CommandContext.getContext());
            inboundOrderCommand.setOrderNo(vo.getInboundOrderNo());
            InboundOrderVo inboundOrderVo = inboundOrderService.getInboundOrderByOrderNo(inboundOrderCommand);
            
            
            // 组装发货仓信息
            WarehouseInfo dispatchWarehouseInfo = new WarehouseInfo();
            dispatchWarehouseInfo.setWarehouseCode(inboundOrderVo.getDestWhCode());
            vo.setDispatchWarehouseInfo(dispatchWarehouseInfo);
            
            // 获取转存次序最高的存储仓编码
            DispatchStorageRelVo deliveryWhRelStoreWh =null;
            // 组装目的仓信息
            WarehouseInfo destinationWarehouseInfo = new WarehouseInfo();
            if (StringUtils.isBlank(vo.getMarkUp())) {
                deliveryWhRelStoreWh = this.getDeliveryWhRelStoreWh(inboundOrderVo.getDestWhCode());
                if (null == deliveryWhRelStoreWh) {
                    throw new ApiException(ErrorCode._02010250304);
                }
                // 组装目的仓信息
                destinationWarehouseInfo.setWarehouseCode(deliveryWhRelStoreWh.getStorageWarehouseCode());
            } else {
                destinationWarehouseInfo.setWarehouseCode(inboundOrderVo.getDestWhCode());
            }
            vo.setDestinationWarehouseInfo(destinationWarehouseInfo);
            
            // 组装产品信息
            ProductInfo productInfo = new ProductInfo();
            productInfo.setWinitProductCode(pscInstance.getPscCode());
            vo.setProductInfo(productInfo);
            
            command.setOrderVo(vo);
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        // 越库转存下一步,生成转存单以及保存商品信息
        command.setCtx(CommandContext.getContext());
        AllocationOrderVo allocationOrderVo = allocationOrderService.createCrossDumpOrder(command);
        
        Map<String, Object> resultMap = new HashMap<String, Object>();
        resultMap.put("orderNo", allocationOrderVo.getOrderNo());
        resultMap.put("dispatchWarehouseName", allocationOrderVo.getDispatchWarehouseInfo().getWarehouseName());  //发货仓
        resultMap.put("destinationWarehouseName", allocationOrderVo.getDestinationWarehouseInfo().getWarehouseName()); // 存储仓
        resultMap.put("winitProductName", allocationOrderVo.getProductInfo().getWinitProductName()); //产品名称
        responseMsg.setData(resultMap);
        responseMsg.setMsg("SUCCESS");
        return SUCCESS;
    }
    
    /**
     * 越库-取消越库
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/cancelCrossDock")
    public String cancelCrossDock(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        Object obj = requestMsg.getData();
        CancelCrossDumpOrderCommand command = new CancelCrossDumpOrderCommand();
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            ValidateUtil.validNotNull(json, "orderNo");
            command.setOrderNo(json.getString("orderNo"));
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        command.setCtx(CommandContext.getContext());
        allocationOrderService.cancelCrossDumpOrder(command);;
        responseMsg.setMsg("SUCCESS");
        return SUCCESS;
    }
    
    /**
     * 越库-提交越库
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/submitCrossDock")
    public String submitCrossDock(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        Object obj = requestMsg.getData();
        SubmitAllocationOrderCommand command = new SubmitAllocationOrderCommand();
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            ValidateUtil.validNotNull(json, "orderNo");
            AllocationOrderVo orderVo = new AllocationOrderVo();
            orderVo.setOrderNo(json.getString("orderNo"));
            command.setOrder(orderVo);
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        command.setCtx(CommandContext.getContext());
        allocationOrderService.submit(command);
        responseMsg.setMsg("SUCCESS");
        return SUCCESS;
    }
    
    /**
     * 
     * 获取默认的psc实例编码.
     * @param type
     * @return
     */
    private DefaultPscConfigVo getDefaultPscInstanceCode(String type) {
        QueryDefaultPscConfigCommand command = new QueryDefaultPscConfigCommand();
        command.setCtx(CommandContext.getContext());
        command.setTypeValue(type);
        return upsStorageWarehouseService.queryDefaultPscConfig(command);
    }
    
    /**
     * 
     * 获取转存次序最高的存储仓.
     * @param dispatchWarehouseCode
     * @return
     */
    private DispatchStorageRelVo getDeliveryWhRelStoreWh(String dispatchWarehouseCode) {
        QueryStorageByDispatchCommand command = new QueryStorageByDispatchCommand();
        command.setCtx(CommandContext.getContext());
        command.setDispatchWarehouseCode(dispatchWarehouseCode);
        List<DispatchStorageRelVo> list = upsStorageWarehouseService.queryStorageByDispatchCode(command);
        if (null == list || list.size() == 0) {
            return null;
        } else {
            // 按转存次序进行排序,升序
            Collections.sort(list, new Comparator<DispatchStorageRelVo>() {

                @Override
                public int compare(DispatchStorageRelVo o1, DispatchStorageRelVo o2) {
                    return o1.getStorageOrder().compareTo(o2.getStorageOrder());
                }
            });
            // 取第一个，数值最小
            return list.get(0);
        }

    }
    
    /**
     * 
     * 根据单据号和单品条码查询调拨单信息.
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/queryInfoByDocNoAndItemSerno")
    public String queryInfoByDocNoAndItemSerno(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg){
        OrderAndMerchandiseQueryCommand command = new OrderAndMerchandiseQueryCommand();
        Object obj = requestMsg.getData();
        if (obj instanceof JSONArray) {
            List<OrderAndMerchandiseVo> list = new ArrayList<OrderAndMerchandiseVo>();
            JSONArray jsonArr = (JSONArray) obj;
            for (Object o : jsonArr) {
                JSONObject detail = (JSONObject) o;
                OrderAndMerchandiseVo vo = new OrderAndMerchandiseVo();
                // 单据号
                vo.setDocNo(detail.getString("docNo"));
                
                // 单品条码
                vo.setItemSerno(detail.getString("itemSerno"));
                list.add(vo);
            }
            command.setCtx(CommandContext.getContext());
            command.setOrderList(list);
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        List<Object> result = allocationOrderService.queryInfoByDocNoAndItemSerno(command);
        responseMsg.setData(result);
        return SUCCESS;
    }
}
